/* **********************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This source code is subject to terms and conditions of the Shared Source License
* for DSL Editor PowerToy. A copy of the license can be found in the License.htm file
* at the root of this distribution. If you can not locate the Shared Source License
* for DSL Editor PowerToy, please obtain a copy from: http://www.codeplex.com/dsltreegrideditor/Project/License.aspx.
* By using this source code in any fashion, you are agreeing to be bound by
* the terms of the Shared Source License for DSL Editor PowerToy.
*
* You must not remove this notice, or any other, from this software.
*
* **********************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

using VSTrid = Microsoft.VisualStudio.VirtualTreeGrid;

using DslEditorPowerToy.Controls.VirtualTreeGrid.Validation;

namespace DslEditorPowerToy.Controls.VirtualTreeGrid
{
    public delegate void SelectionChangedEventHandler(object sender, SelectionChangedEventArgs e);
    public delegate void DataItemChangedEventHandler(object sender, DataItemChangedEventArgs e);
    public delegate void LabelEditChangedEventHandler(object sender, LabelEditChangedEventArgs e);

    public abstract partial class VirtualTreeGridHostBase : UserControl
    {
        private VirtualTreeGridControl _treeGridControl = null;

        #region Constructors
        public VirtualTreeGridHostBase(VirtualTreeGridControl treegridInstance)
            : base()
        {
            ArgumentValidator.ValidateNotNull("TreeGridInstance", treegridInstance);

            this._treeGridControl = treegridInstance;
            //Initialise control
            this._treeGridControl.AccessibleRole = System.Windows.Forms.AccessibleRole.Outline;
            this._treeGridControl.Dock = System.Windows.Forms.DockStyle.Fill;
            this._treeGridControl.FullCellSelect = true;
            this._treeGridControl.HasHorizontalGridLines = true;
            this._treeGridControl.Location = new System.Drawing.Point(0, 0);
            this._treeGridControl.MultiColumnHighlight = true;
            this._treeGridControl.DataSource = null;
            this._treeGridControl.Size = new System.Drawing.Size(495, 350);
            this._treeGridControl.TabIndex = 0;
            this._treeGridControl.SelectionChanged += new System.EventHandler(this.treegridControlSelectionChanged);
            this._treeGridControl.LabelEditControlChanged += new System.EventHandler(this.treegridControlLabelEditControlChanged);
            this._treeGridControl.ItemCountChanged += new Microsoft.VisualStudio.VirtualTreeGrid.ItemCountChangedEventHandler(this.treegridControlItemCountChanged);
            this._treeGridControl.ItemMoved += new Microsoft.VisualStudio.VirtualTreeGrid.ItemMovedEventHandler(this.treegridControlItemMoved);
            this._treeGridControl.DisplayDataChanged += new Microsoft.VisualStudio.VirtualTreeGrid.DisplayDataChangedEventHandler(this.treegridControlDisplayDataChanged);
            this.Controls.Add(this._treeGridControl);

            InitializeComponent();

        }
        #endregion

        #region Public Events
        /// <summary>
        /// Raised when selection in the tree changes
        /// </summary>
        public event SelectionChangedEventHandler SelectionChanged;
        /// <summary>
        /// Raised when an item is moved in the tree
        /// </summary>
        public event VSTrid.ItemMovedEventHandler ItemMoved;
        /// <summary>
        /// Raised when the visible item count is changed
        /// </summary>
        public event VSTrid.ItemCountChangedEventHandler ItemCountChanged;
        /// <summary>
        /// Raised when an item's dataItem has changed
        /// </summary>
        public event DataItemChangedEventHandler DataItemChanged;
        /// <summary>
        /// Raised when label editing changed
        /// </summary>
        public event LabelEditChangedEventHandler LabelEditChanged;
        #endregion

        #region Public Properties
        public virtual object DataSource
        {
            get
            {
                if (null == this._treeGridControl)
                    return null;
                else
                    return this._treeGridControl.DataSource;
            }
            set
            {
                if (null != this._treeGridControl)
                {
                    this._treeGridControl.DataSource = value;
                    DisplayControls();
                }
            }
        }
        /// <summary>
        /// Gets the current selection
        /// </summary>
        public object CurrentSelection
        {
            get
            {
                if ((null == this._treeGridControl) 
                    ||(null == this._treeGridControl.Tree))
                    return null;

                VSTrid.VirtualTreeItemInfo info = this._treeGridControl.Tree.GetItemInfo(this._treeGridControl.CurrentIndex,
                    this._treeGridControl.CurrentColumn, false);
                Branches.IDataItemBranch currentBranch = (Branches.IDataItemBranch)info.Branch;
                return currentBranch.GetDataItem(info.Row);
            }
        }
        #endregion

        #region Protected Properties
        /// <summary>
        /// Gets the text to display when there is no selection
        /// </summary>
        protected abstract string NoSelectionText
        {
            get;
        }
        /// <summary>
        /// Returns the instance of the contained tree grid control
        /// </summary>
        protected  VirtualTreeGridControl TreeGridControl
        {
            get
            {
                return this._treeGridControl;
            }
        }
        #endregion

        #region Control Handlers
        private void treegridControlSelectionChanged(object sender, EventArgs e)
        {
            OnSelectionChanged();
        }

        private void treegridControlItemMoved(object sender, VSTrid.ItemMovedEventArgs e)
        {
            OnItemMoved(e);
        }

        private void treegridControlItemCountChanged(object sender, VSTrid.ItemCountChangedEventArgs e)
        {
            OnItemCountChanged(e);
        }

        private void treegridControlDisplayDataChanged(object sender, VSTrid.DisplayDataChangedEventArgs e)
        {
            OnDataItemChanged(e);
        }
        private void treegridControlLabelEditControlChanged(object sender, EventArgs e)
        {
            OnLabelEditControlChanged(e);
        }

        #endregion

        #region Protected Methods
        /// <summary>
        /// Raises OnSelectionChanged event
        /// </summary>
        /// <param name="e"></param>
        protected void OnSelectionChanged()
        {
            if (null != this.SelectionChanged)
            {
                VSTrid.VirtualTreeItemInfo info = this._treeGridControl.Tree.GetItemInfo(this._treeGridControl.CurrentIndex,
                    this._treeGridControl.CurrentColumn, false);
                Branches.IDataItemBranch currentBranch = (Branches.IDataItemBranch)info.Branch;
                string propertyName = currentBranch.GetDataItemPropertyName(info.Column);

                this.SelectionChanged(this, new SelectionChangedEventArgs(this.CurrentSelection, propertyName));
            }
        }
        /// <summary>
        /// Raises ItemMoved event
        /// </summary>
        /// <param name="e"></param>
        protected void OnItemMoved(VSTrid.ItemMovedEventArgs e)
        {
            if (null != this.ItemMoved)
                this.ItemMoved(this, e);
        }
        /// <summary>
        /// Raises ItemMoved event
        /// </summary>
        /// <param name="e"></param>
        protected void OnItemCountChanged(VSTrid.ItemCountChangedEventArgs e)
        {
            if (null != this.ItemCountChanged)
                this.ItemCountChanged(this, e);
        }
        /// <summary>
        /// Raises DataItemChanged event
        /// </summary>
        /// <param name="e"></param>
        protected void OnDataItemChanged(VSTrid.DisplayDataChangedEventArgs e)
        {
            if (null != this.DataItemChanged)
            {
                VSTrid.VirtualTreeItemInfo info = this._treeGridControl.Tree.GetItemInfo(e.StartRow,
                    e.Column, false);
                Branches.IDataItemBranch currentBranch = (Branches.IDataItemBranch)info.Branch;
                string propertyName = currentBranch.GetDataItemPropertyName(info.Column);
                object propertyValue = currentBranch.GetDataItemPropertyValue(info.Row, info.Column);
                object dataItem = currentBranch.GetDataItem(info.Row);
                this.DataItemChanged(this, new DataItemChangedEventArgs(dataItem,
                    propertyName, propertyValue));
            }
        }
        /// <summary>
        /// Raises LabelEditChanged event
        /// </summary>
        /// <param name="e"></param>
        protected void OnLabelEditControlChanged(EventArgs e)
        {
            if (null != this.LabelEditChanged)
                this.LabelEditChanged(this, new LabelEditChangedEventArgs(this._treeGridControl.LabelEditControl));
        }
        #endregion

        #region Private Methods
        private void DisplayControls()
        {
            this._treeGridControl.Visible = (null != this.DataSource);
            this._treeGridControl.Enabled = (null != this.DataSource);
            this.bannerLabel.Text = this.NoSelectionText;
            this.noSelectionPanel.Visible = (null == this.DataSource);
        }
        #endregion

    }
}
